package info.batcloud.fanli.api.controller;

import com.alibaba.fastjson.JSON;
import info.batcloud.fanli.api.controller.form.WeixinLoginForm;
import info.batcloud.fanli.core.domain.BusinessResponse;
import info.batcloud.fanli.core.entity.User;
import info.batcloud.fanli.core.entity.WeixinAccount;
import info.batcloud.fanli.core.enums.Gender;
import info.batcloud.fanli.core.repository.UserRepository;
import info.batcloud.fanli.core.repository.WeixinAccountRepository;
import info.batcloud.fanli.core.service.UserService;
import info.batcloud.fanli.core.service.WeixinAccountService;
import info.batcloud.fanli.core.weixin.WxaConfig;
import info.batcloud.fanli.core.weixin.domain.UserInfo;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.inject.Inject;
import java.io.IOException;
import java.util.Date;

/**
 * Created by Administrator on 2017-06-23.
 */
@Controller
@RequestMapping("/api/login/weixin")
public class WxLoginController {

    @Inject
    private UserService userService;

    @Inject
    private UserRepository userRepository;

    @Inject
    private WeixinAccountRepository weixinAccountRepository;

    @Inject
    private WxaConfig wxaConfig;

    @GetMapping
    @ResponseBody
    @Transactional
    public BusinessResponse wxLogin(WeixinLoginForm loginForm) throws IOException {
        BusinessResponse res = new BusinessResponse<>();
        CloseableHttpClient client = HttpClientBuilder.create().build();
        HttpGet httpGet = new HttpGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + wxaConfig.getAppid()
                + "&secret=" + wxaConfig.getSecret() + "&js_code=" + loginForm.getCode() + "&grant_type=authorization_code");
        HttpResponse response = client.execute(httpGet);
        String result = EntityUtils.toString(response.getEntity());
        client.close();
        WeixinSession weixinSession = JSON.parseObject(result, WeixinSession.class);
        //验证getUserInfo的signature
        String signStr = loginForm.getRawData() + weixinSession.getSessionKey();
        String checkSign = new String(DigestUtils.sha1(signStr.getBytes("utf8")));
        if(!checkSign.equals(loginForm.getSignature())) {
            return BusinessResponse.error("微信登录认证失败，请联系客服进行咨询！");
        }
        WeixinAccount weixinAccount = weixinAccountRepository.findByOpenId(weixinSession.getOpenid());
        if(weixinAccount == null) {
            weixinAccount = new WeixinAccount();
        }
        UserInfo userInfo = loginForm.getUserInfo();
        weixinAccount.setAvatarUrl(userInfo.getAvatarUrl());
        weixinAccount.setCity(userInfo.getCity());
        weixinAccount.setCountry(userInfo.getCountry());
        weixinAccount.setGender(userInfo.getGender() + "");
        weixinAccount.setNickname(userInfo.getNickName());
        weixinAccount.setProvince(userInfo.getProvince());
        weixinAccount.setOpenId(weixinSession.getOpenid());
        weixinAccount.setUnionId(weixinSession.getUnionid());
        User user;
        if(weixinAccount.getUserId() == null) {
            user = new User();
            user.setCreateTime(new Date());
        } else {
            user = userRepository.findOne(weixinAccount.getUserId());
        }
        user.setNickname(userInfo.getNickName());
        user.setLocked(false);
        user.setAvatarUrl(userInfo.getAvatarUrl());
        user.setCity(userInfo.getCity());
        user.setCountry(userInfo.getCountry());
        user.setGender(userInfo.getGender() == 1 ? Gender.MALE : Gender.FAMALE);
        userRepository.save(user);
        weixinAccount.setUserId(user.getId());
        weixinAccountRepository.save(weixinAccount);
        return res;
    }

    public static class WeixinSession {
        private String openid;
        private String sessionKey;
        private String unionid;

        public String getOpenid() {
            return openid;
        }

        public void setOpenid(String openid) {
            this.openid = openid;
        }

        public String getSessionKey() {
            return sessionKey;
        }

        public void setSessionKey(String sessionKey) {
            this.sessionKey = sessionKey;
        }

        public String getUnionid() {
            return unionid;
        }

        public void setUnionid(String unionid) {
            this.unionid = unionid;
        }
    }

}
